package com.chenfan.magic.interpreter;

import com.alibaba.fastjson.JSON;
import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.core.MagicLogPublisher;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.utils.FastJsonKit;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.python.core.PyFunction;
import org.python.core.PyObject;
import org.python.core.PyString;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * Python动态解释器
 * <p>
 * 示例:
 * String code = "import json \n";
 * code += "def handler(scope): \n";
 * code += "   print(sys.path) \n";
 * code += "   print(scope)\n";
 * code += "   myjson = json.loads(scope)\n";
 * code += "   return myjson[\"hh\"]\n";
 * run(code, paramMap);
 *
 * @author caohui
 */
@Slf4j
@Component
@AllArgsConstructor
public class PythonInterpreter implements __IInterpreter {

    public static final String TYPE_CODE = "python";
    public static final String ALIAS = "py";

    @Qualifier("pythonInterpreterEngine")
    private org.python.util.PythonInterpreter pythonInterpreterEngine;

    /**
     * jython解释执行
     *
     * @param code
     * @param paramMap
     * @return
     */
    @Override
    public Object run(Map<String, Object> idcRuntimePool, String code, Map<String, Object> paramMap) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        ttlDetailModel.start();
        Object result = null;
        try {
            pythonInterpreterEngine.exec(code);
            PyFunction func = (PyFunction) pythonInterpreterEngine.get(__IInterpreter.HANDER_NAME,
                    PyFunction.class);
            PyObject pyobj = func.__call__(new PyString(JSON.toJSONString(paramMap)));
            result = FastJsonKit.jsonstring2Map(pyobj.toString());
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, code, result, paramMap, ttlDetailModel.end().getTtl() + "");
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, e);
            MagicLogPublisher.publishInterpreterEvent(TYPE_CODE, code, result, paramMap, ttlDetailModel.end().getTtl() + "", e);
        }
        return result;
    }

    @Override
    public Object run(Map<String, Object> idcRuntimePool, String expression, String defaultValue) {
        return defaultValue;
    }

}
